--
-- Corrección en la funcion que controla pendientes para el caso de modificacion de cantidades tomadas
--
   
 -- FUNCTION: stock.verificar_grafo_stock(integer, integer, integer, integer, integer, character varying, character varying, character varying, character varying, numeric, numeric)

-- DROP FUNCTION stock.verificar_grafo_stock(integer, integer, integer, integer, integer, character varying, character varying, character varying, character varying, numeric, numeric);

CREATE OR REPLACE FUNCTION stock.verificar_grafo_stock(
	integer,
	integer,
	integer,
	integer,
	integer,
	character varying,
	character varying,
	character varying,
	character varying,
	numeric,
	numeric)
    RETURNS boolean
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE 
AS $BODY$
DECLARE

  pIdArtM ALIAS FOR $1;
  pOldIdArt ALIAS FOR $2;
  pNewIdArt ALIAS FOR $3;
  pOldOrigenIdArtM ALIAS FOR $4;
  pNewOrigenIdArtM ALIAS FOR $5;
  pOldOrigenCodStkEst ALIAS FOR $6;
  pNewOrigenCodStkEst ALIAS FOR $7;
  pOldDestinoCodStkEst ALIAS FOR $8;
  pNewDestinoCodStkEst ALIAS FOR $9;
  pOldCant ALIAS FOR $10;
  pNewCant ALIAS FOR $11;
  vId integer;
  vCantPendiente numeric;
  vCant numeric;
  VIdComm integer;
BEGIN

-- 13/06/2018 Dejo cambiar los estados de stock a un nuevo estado '<A>' que se usará sólo desde programa.

  IF (pOldIdArt != pNewIdArt) THEN
    SELECT Id INTO vId FROM public.artm WHERE (OrigenIdArtM = pIdArtM);
    IF (FOUND) THEN
      RAISE EXCEPTION 'No se puede cambiar el artículo porque otro comprobante ya tomó artículos de éste.';
    END IF;
    PERFORM stock.verificar_cant_tomada(pNewIdArt, pNewCant, pNewOrigenIdArtM);
  END IF;
  IF (pNewOrigenCodStkEst <> '<A>') AND (pOldOrigenIdArtM != pNewOrigenIdArtM) THEN -- Si se cambia el comprobante del cual se toman artículos
    RAISE EXCEPTION 'No se puede cambiar el comprobante del cual se toman artículos, ArtM.OrigenIdArtM.';
  END IF;
  IF (pNewOrigenCodStkEst <> '<A>') AND (pOldOrigenCodStkEst != pNewOrigenCodStkEst) THEN -- Si se cambia el nodo origen
    RAISE EXCEPTION 'No se puede cambiar el nodo de origen, ArtM.OrigenCodStkEst.';
  END IF;
  IF (pNewOrigenCodStkEst <> '<A>') AND (pOldDestinoCodStkEst != pNewDestinoCodStkEst) THEN -- Si cambió el nodo destino
    SELECT Id INTO vId FROM public.ArtM WHERE (OrigenIdArtM = pIdArtM);
    IF (FOUND) THEN
      RAISE EXCEPTION 'Existe un comprobante que tomó artículos de este comprobante.';
    END IF;
  END IF; -- Si cambió el nodo destino
  IF (pOldCant <> pNewCant) THEN -- Si cambió la cantidad
    IF (pOldOrigenIdArtM IS NOT NULL) THEN -- Si se tomaron artículos de otro comprobante ...
	  vIdComm := (Select idcomm from artm where artm.id = pIdArtM);
      SELECT origen.cantpendiente + sum(actual.cant) INTO vCantPendiente 
	  FROM public.artm origen
	  INNER JOIN public.artm actual on actual.idcomm = vIdComm and actual.origenIdArtm = pOldOrigenIdArtM
	  WHERE origen.Id = pOldOrigenIdArtM
	  group by origen.cantpendiente;
      IF ((pNewCant - pOldCant) > vCantPendiente) THEN -- Si se intenta tomar mas artículos que los pendientes en el comprobante del cual se tomaron artículos
        RAISE EXCEPTION 'Se excede la cantidad de artículos disponible de tomar del otro comprobante.';
      END IF;
    END IF;
    SELECT coalesce(Sum(Cant),0) INTO vCant FROM public.artm WHERE (OrigenIdArtM = pIdArtM);
    IF (FOUND) AND (pNewCant < vCant) THEN -- Si la nueva cantidad NO permite abastecer a todos los comprobante que toman artículos de este movimiento
      RAISE EXCEPTION 'No puede establecer una cantidad inferior a la tomada de este movimiento por otros comprobantes.';
    END IF;
  END IF; -- Si cambió la cantidad
  RETURN TRUE;
END;
$BODY$;

ALTER FUNCTION stock.verificar_grafo_stock(integer, integer, integer, integer, integer, character varying, character varying, character varying, character varying, numeric, numeric)
    OWNER TO abacouser;

COMMENT ON FUNCTION stock.verificar_grafo_stock(integer, integer, integer, integer, integer, character varying, character varying, character varying, character varying, numeric, numeric)
    IS 'Verifica si modificar el arco de stock de un movimiento es válido. No comprueba si es un arco válido porque se necesita otro query para obtener el comprobante.';
  
  
--
SELECT aaversion('518.09','518.08');
--

